﻿// Serotonin -- easy-to-use image filters application
// https://code.google.com/p/serotonin/
//
// Copyright © Frank Nagl, 2012-2013
// admin@franknagl.de
//

using System;

namespace Serotonin
{
    using Helper;
    using System.Drawing;
    using System.Windows.Forms;

    /// <summary>Declares the event handler for applying a filter.</summary>
    public delegate void ApplyEventHandler();

    /// <summary> Manages the images and the image GUI panel. </summary>
    public class Processor
    {
        /// <summary>Handles the ApplyEvent at the client.</summary>
        public ApplyEventHandler ApplyEvent;

        /// <summary> Filter information, used for image matadata.
        /// </summary>
        public string FilterText { get; private set; }

        /// <summary> The groupbox with process and reset button of the 
        /// specified options form. </summary>
        public GroupBox GbProcess
        {
            get { return gbProcess; }
            set
            {
                bool b = false;
                if (gbProcess != null)
                {
                    b = gbProcess.Enabled;
                }
                gbProcess = value;
                gbProcess.Enabled = b;
                // GbProcess.Enabled = !realtimeProcessing;
            }
        }

        /// <summary> The path and filename of 
        /// <see cref="OriginalImage"/>.</summary>
        public string ImageFilename { get; private set; }

        /// <summary> The original image.</summary>
        public Bitmap OriginalImage { get; private set; }

        /// <summary>
        /// Determines whether the simple filter will be processed in real-time
        /// or not (if filter supports real-time processing).
        /// </summary>
        public bool RealtimeProcessing
        {
            get { return realtimeProcessing; }
            set
            {
                realtimeProcessing = value;

                //if (GbProcess != null)
                //{
                //    GbProcess.Enabled = !value;
                //}

                if (!value)
                {
                    Reset();
                }
                else
                {
                    InvokeEvents();
                }
            }
        }

        /// <summary> The working image (could be original or processed 
        /// result image).</summary>
        public Bitmap WorkingImage { get; set; }

        private GroupBox gbProcess;        
        private readonly Panel panel;
        private bool realtimeProcessing;

        /// <summary>
        /// Initializes a new instance of the <see cref="Processor" /> class.
        /// </summary>
        /// <param name="originalImage">The original image to process.</param>
        /// <param name="imageFilename">The path and filename of
        /// <paramref name="originalImage" /></param>
        /// <param name="panel">The panel to show the (processed) image.</param>
        public Processor(Bitmap originalImage, 
                         string imageFilename, 
                         Panel panel)
        {
            // not necessary, will be done by Reset()-method
            // FilterText = Program.L.Text[40] + Program.L.Text[41];
            OriginalImage = originalImage;
            ImageFilename = imageFilename;
            WorkingImage = originalImage.Clone() as Bitmap;
            this.panel = panel;
            // SetImageToPanel(); // not necessary, will be done by Reset()-method
        }

        /// <summary>
        /// Fires the apply filter event, if <see cref="RealtimeProcessing"/> 
        /// is true.
        /// </summary>
        public void ApplyFilterRTP()
        {
            if (realtimeProcessing)
            {
                InvokeEvents();                 
            }
        }

        /// <summary>
        /// Changes ONLY the <see cref="FilterText" /> to
        /// the specified <paramref name="filterText" />.
        /// </summary>
        /// <param name="filterText">Filter information, 
        /// used for image matadata.</param>
        public void Change(string filterText)
        {            
            FilterText = filterText;
            FilterText = StringBuilder.ReplaceGermanUmlauts(FilterText);
        }

        /// <summary>
        /// Changes the <see cref="panel" /> and <see cref="WorkingImage" /> to
        /// the specified <paramref name="newImage" />.
        /// </summary>
        /// <param name="newImage">The new image to show and use as working
        /// image.</param>
        /// <param name="filterText">Filter information of <paramref name="newImage"/>, 
        /// used for image matadata.</param>
        public void Change(Bitmap newImage, string filterText)
        {
            FilterText = filterText;
            FilterText = StringBuilder.ReplaceGermanUmlauts(FilterText);
            WorkingImage = newImage;
            SetImageToPanel();
            M.MinimizeMemory();
        }

        /// <summary> Removes all (except last) apply events. </summary>
        public void RemoveAllApplyEvents()
        {
            if (ApplyEvent != null)
            {
                Delegate[] delegates = ApplyEvent.GetInvocationList();
                foreach (Delegate d in delegates)
                {                    
                    // ReSharper disable DelegateSubtraction
                    ApplyEvent -= (ApplyEventHandler) d;
                    // ReSharper restore DelegateSubtraction
                }
            }
        }

        /// <summary> Resets Serotonin to original image. </summary>
        public void Reset()
        {
            WorkingImage = OriginalImage.Clone() as Bitmap;
            SetImageToPanel();
            M.MinimizeMemory();
            FilterText = Program.L.Text[40] + Program.L.Text[41];
        }

        private void InvokeEvents()
        {
            if (ApplyEvent != null)
            {
                ApplyEvent.Invoke();
            }
        }

        private void SetImageToPanel()
        {
            Console.WriteLine("SetImageToPanel");
            // new Controls.SimpleImageViewer(WorkingImage);
            panel.BackgroundImage = new Bitmap(WorkingImage, panel.Size);            
        }
    }
}
